#include <iostream>
//#include <thread> //c++
#include <pthread.h>
#include <unistd.h>
#include <vector>
#include "pthread.hpp"
#include "lockgroup.hpp"
using namespace std;
using namespace Thread;

int g_tickets = 10000;
//pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
class ThreadData
{
public:
    ThreadData(int& tickets,string name,pthread_mutex_t mutex)
    :_tickets(tickets)
    ,_name(name)
    ,total(0)
    ,_mutex(mutex)
    {}
    ~ThreadData()
    {}
public:
    int& _tickets;
    string _name;
    int total;
    pthread_mutex_t _mutex;
};

void route(ThreadData* t)
{
    while(1)
    {
        lockgroup lockgroup(t->_mutex);
        lockgroup.lock();
        if(t->_tickets > 0)
        {
            usleep(100);
            printf("%s:running , get tickets:%d\n",t->_name.c_str(),t->_tickets);
            t->_tickets--;
            lockgroup.unlock();
            t->total++;
        }
        else
        {
            lockgroup.unlock();
            break;
        }
    }
}



int main()
{
    vector<thread<ThreadData*>> threads;
    vector<ThreadData*> data;
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,nullptr);
    // 1. 创建一批线程
    for (int i = 0; i < 4; i++)
    {
        std::string name = "thread-" + std::to_string(i + 1);
        ThreadData* t = new ThreadData(g_tickets,name,mutex);
        threads.emplace_back(route, t, name);
        data.emplace_back(t);
    }

    // 2. 启动 一批线程
    for (auto& thread : threads)
    {
        thread.start();
    }

    // 3. 等待一批线程
    for (auto& thread : threads)
    {
        thread.join();
        //std::cout << "wait thread done, thread is: " << thread.getname() << std::endl;
    }
    
    //4.打印总数
    for(auto& t : data)
    {
        cout << t->_name << " total is : " << t->total<<endl;
    }


    // Thread<int> t1(print, 10);
    // t1.Start();
    // std::cout << "name: " << t1.name() << std::endl;
    // t1.Join();
    return 0;
}




// void Print(int count)
// {
//     while(count--)
//     {
//         cout<< "I am new thread" << " count: "<< count <<endl;
//         sleep(1);
//     }
// }






















// int main()
// {
//     thread<int> newthread(Print,5);
//     newthread.start();
//     newthread.join();
// }






























// __thread int val = 5;
// string ToHex(pthread_t tid)
// {
//     char id[64];
//     snprintf(id, sizeof(id), "0x%lx", tid);
//     return id;
// }




// void* threadrun1(void* args)
// {
//     string name = static_cast<const char*>(args);
//     int count = 5;
//     while(count--)
//     {
//         val--;
//         cout<< "I am new thread:"<< name <<" val: "<< val <<endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// void* threadrun2(void* args)
// {
//     string name = static_cast<const char*>(args);
//     int count = 5;
//     while(count--)
//     {
//         cout<< "I am new thread:"<< name <<" val: "<< val <<endl;
//         sleep(1);
//     }
//     return nullptr;
// }



// int main()
// {
//     pthread_t tid1;
//     pthread_create(&tid1,nullptr,threadrun1,(void*)"thread-1");
//     pthread_t tid2;

//     pthread_create(&tid2,nullptr,threadrun2,(void*)"thread-2");

//     //pthread_detach(tid);

//     while(1)
//     {
//         sleep(1);
//         //cout << "I am main thread" <<" tid: "<<ToHex(pthread_self())<<" val: "<< val <<endl;
//     }

    
// }












// void* threadrun(int count)
// {
//     while(count--)
//     {
//         cout<< "I am new thread:"<<" tid: "<<ToHex(pthread_self())<<endl;
//         sleep(1);
//     }
//     cout<<"new thread end"<<endl;
//     return nullptr;
// }

// int main()
// {

//     thread t1(threadrun,5);
//     while(1)
//     {
//         cout << "I am main thread" <<" tid: "<<ToHex(pthread_self())<<endl;
//         sleep(1);
//     }

//     t1.join();
// }